% Authors: Francisco Pinto & Bruno Maia
% Date: 22-09-2011
% This file is part of "Breakthrough"

?- use_module(library(sockets)).

?- ensure_loaded('breakthrough.pro').

% Generic socket interface

port(60001).

server:-
        port(Port),
        socket_server_open(Port,Socket),
        socket_server_accept(Socket, _Client, Stream, [type(text)]),
        server_loop(Stream),
        socket_server_close(Socket),
        write('Server Exit'),nl.

server_loop(Stream) :-
        repeat,
                read(Stream, ClientRequest),
                write('Received: '), write(ClientRequest), nl, 
                server_input(ClientRequest, ServerReply),
                format(Stream, '~q.~n', [ServerReply]),
                write('Send: '), write(ServerReply), nl, 
                flush_output(Stream),
        (ClientRequest == bye; ClientRequest == end_of_file), !.

server_input(new_game, ok(Board, Player)):- 
        initial_board(Board), 
        player1_representation(Player),
        !.

server_input(load_game, ok(Board, Player)):-
        load_game([Board, Player]),
        !.

server_input(board_width, ok(BoardWidth)) :-
	board_size(BoardWidth),
	!.

server_input(valid_move([[XPiece,YPiece],[XFinal,YFinal]] , Board, Player), ok):- 
        get_board_element(Board, XPiece, YPiece, Player),
        valid_movement(Board, XPiece, YPiece, XFinal, YFinal, Player), 
        !.

server_input(ai_move(Board, Player, Difficulty), ok([[XPiece,YPiece],[XFinal,YFinal]])):-
        assert(first(Player)),
        assert(player_difficulty(Player, Difficulty)),
        adapt_depth(Player, Board, Depth),
        minimax(Player, Board, NewBoard, Depth),
        findall([XP, YP, XF, YF],
          (
            find_piece(Board, Player, 0, 0, XP, YP),
            valid_movement(Board, XP, YP, XF, YF, Player),
            move(Board, XP, YP, XF, YF, Player, Temp),
            Temp = NewBoard
          ),
          [[XPiece, YPiece, XFinal, YFinal]]),
        retract(player_difficulty(Player, Difficulty)),
        retract(first(Player)),
        !.

server_input(possible_moves(Board, Player, [XPiece, YPiece]), ok(PossibleMoves)):-
        get_board_element(Board, XPiece, YPiece, Player),
        findall([XFinal, YFinal],
          (
            valid_movement(Board, XPiece, YPiece, XFinal, YFinal, Player)
          ),
          PossibleMoves),
        !.

server_input(winner(Board, Player), ok) :-
       winner(Board, Player), !.

server_input(bye, ok):-!.
server_input(end_of_file, ok):-!.
server_input(_, invalid) :- !.
